home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / networking / amitcp / dialupv3.03.lha / dialup / io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-03  |  9.2 KB  |  340 lines

  1. #include "dialup.h"
  2.  
  3. extern const UBYTE             *prgname;
  4. extern struct IOExtSer        *serialIOReq;
  5. extern struct timerequest    *timereq;
  6. extern BPTR                    repfile;
  7. extern UBYTE                *rxbuffer;
  8. extern LONG                    arg[];
  9.  
  10. BOOL    isend( UBYTE *send );            /* real send with \r, \n and \t remapping, string must be in a bigger buffer */
  11.  
  12. UBYTE *
  13. expectFromSer( UBYTE *expect, USHORT waittime )
  14.     {
  15.     UBYTE *result = NULL;
  16.     ULONG WaitMask, timebit, serbit, wres;
  17.  
  18.     WaitMask = 0;
  19.  
  20.     if ( waittime )
  21.         {
  22.         if ( arg[A_VERBOSE] && !expect ) msg("waiting %ld seconds\n", expect, waittime);
  23.         timebit = 1L << timereq->tr_node.io_Message.mn_ReplyPort->mp_SigBit;
  24.         SetSignal(0L, timebit);
  25.         WaitMask |= SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | timebit;
  26.         timereq->tr_node.io_Command = TR_ADDREQUEST;
  27.         timereq->tr_time.tv_secs    = waittime;
  28.         timereq->tr_time.tv_micro    = 0;
  29.         SendIO((struct IORequest *)timereq);
  30.         if ( !expect )
  31.             {
  32.             while ( ! ( (wres = Wait(WaitMask)) & WaitMask ) ); /* Wait for the timeout, no string expected! */
  33.             if ( wres & timebit ) { *rxbuffer = '\0'; result = rxbuffer; };
  34.             };
  35.         };
  36.  
  37.     if ( expect )
  38.         {
  39.         UBYTE *wptrb;
  40.         UBYTE *repptr;
  41.  
  42.         UBYTE mbuf[MAXMATCHSTRING * 25];
  43.         UBYTE *msa[MAXMATCHSTRING];
  44.  
  45.         if ( strlen(expect) > sizeof(mbuf) )
  46.             {
  47.             msg("expectFromSer: expectstring to long!");
  48.             _FAIL_;
  49.             };
  50.  
  51.         if ( arg[A_VERBOSE] ) msg("expecting %s for %ld seconds\n", expect, waittime);
  52.  
  53.         buildMatchStringArray(expect, mbuf, msa);
  54.  
  55.         serbit =  1L << serialIOReq->IOSer.io_Message.mn_ReplyPort->mp_SigBit;
  56.         SetSignal(0L, serbit);
  57.         WaitMask |= SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | serbit;
  58.         wptrb = repptr = rxbuffer;
  59.         wres = 0;
  60.         do    {
  61.             UBYTE *spt;    
  62.  
  63.             serialIOReq->IOSer.io_Command  = SDCMD_QUERY;
  64.             DoIO((struct IORequest *)serialIOReq);
  65.             serialIOReq->IOSer.io_Command  = CMD_READ;
  66.             serialIOReq->IOSer.io_Data       = (APTR)wptrb;
  67.             /* while there are chars on the serial, set and get them (upto bufsize): */
  68.             if ( ( serialIOReq->IOSer.io_Length = min(serialIOReq->IOSer.io_Actual, RXBUFSIZE - (wptrb - rxbuffer)) ) > 0 )
  69.                 {
  70.                 DoIO((struct IORequest *)serialIOReq);
  71.                 wptrb += serialIOReq->IOSer.io_Actual;
  72.                 continue;
  73.                 }
  74.             *wptrb = '\0'; /* Terminate received string and replace any received \0's with spaces, to make a stringsearch possible: */
  75.             while ( spt = memchr(repptr, '\0', wptrb - repptr ) ) memmove(spt, spt + 1, wptrb-- - spt);
  76.  
  77.             /* Report the conversation. The modem echos commands sent to it: */
  78.             if ( repfile && wptrb > repptr ) { Write( repfile, repptr, wptrb - repptr); repptr = wptrb; };
  79.  
  80.             /* check whether one of the matchstrings is in the receive buffer. Stop and return it if so. */
  81.             if ( result = matchString(rxbuffer, msa) ) break;
  82.  
  83.             /* wait for one char, break or timeout: */
  84.             serialIOReq->IOSer.io_Length = 1;
  85.             SetSignal(0L, serbit);
  86.             SendIO((struct IORequest *)serialIOReq);
  87.             while ( ! ( (wres = Wait(WaitMask)) & WaitMask ) );
  88.             if ( wres & serbit || wres & SIGBREAKF_CTRL_F )
  89.                 {
  90.                 if(CheckIO((struct IORequest *)serialIOReq) )    /* If request is complete... */
  91.                     {
  92.                     WaitIO((struct IORequest *)serialIOReq);    /* clean up and remove reply */
  93.                     wptrb += serialIOReq->IOSer.io_Actual;
  94.                     *wptrb = '\0';                                /* Terminate received string */
  95.                     }
  96.                 }
  97.             else if ( (wres & timebit) )
  98.                 {
  99.                 UBYTE *cbptr;
  100.                 UBYTE *rbptr;
  101.                 UBYTE ccnt;
  102.                 for(rbptr = rxbuffer, cbptr = wptrb + 1; ( rbptr < wptrb ) && ((cbptr + 20) < (rxbuffer + RXBUFSIZE)); rbptr += 8)
  103.                     {
  104.                     cbptr += sprintf(cbptr, "%08lX %08lX  ", *(ULONG *)rbptr, *(ULONG *)(rbptr + 4) );
  105.                     for(ccnt = 0; rbptr[ccnt] && ccnt < 8; ccnt++)
  106.                         if ( strchr("\n\r\t", rbptr[ccnt] ) ) rbptr[ccnt] = 1;
  107.                     cbptr += sprintf(cbptr, "%-.4s ", rbptr);
  108.                     if (rbptr + 4 < wptrb) cbptr += sprintf(cbptr, "%-.4s\n", rbptr + 4 );
  109.                     };
  110.                 msg("TIMEOUT, after waiting %ld secs for:\n'%s'\nReceived:\n%s", waittime, expect, wptrb + 1);
  111.                 }
  112.             }
  113.         while ( ! ( wres & ( SIGBREAKF_CTRL_C | timebit ) ) );
  114.  
  115.         if ( wres & SIGBREAKF_CTRL_C ) { strcpy(wptrb, BREAKSTR); wptrb += sizeof(BREAKSTR); };
  116.  
  117.         if( !CheckIO((struct IORequest *)serialIOReq) ) /* If request is complete... */
  118.             {
  119.             AbortIO((struct IORequest *)serialIOReq);  /* Ask device to abort request, if pending */
  120.             WaitIO((struct IORequest *)serialIOReq);   /* clean up and remove reply */
  121.             if ( SetSignal(0, 0) & serbit ) SetSignal(0, serbit );
  122.             }
  123.  
  124.         if ( repfile && (wptrb > repptr) )
  125.             {
  126.             Write( repfile, repptr, wptrb - repptr); /* Report the conversation, cause normaly modem echos commands sent to it. */
  127.             repptr = wptrb;
  128.             };
  129.         };
  130.  
  131.     if( waittime && !CheckIO((struct IORequest *)timereq) ) /* Abort any pending timer requests */
  132.         {
  133.         AbortIO((struct IORequest *)timereq);
  134.         WaitIO((struct IORequest *)timereq);
  135.         if ( SetSignal(0, 0) & timebit ) SetSignal(0, timebit );
  136.         }
  137.  
  138.     return( result );
  139.     }
  140.  
  141. #define SCRATCHBUFSIZE 1000
  142.  
  143. BOOL
  144. sendLine( UBYTE *send )
  145.     {
  146.     UBYTE buf[SCRATCHBUFSIZE];
  147.  
  148.     if ( strlen(send) >= SCRATCHBUFSIZE - 1 ) _FAIL_
  149.     sprintf(buf, "%s\r", send);
  150.     return(isend(buf));
  151.     }
  152.  
  153. UBYTE *
  154. sendEx( UBYTE *send , UBYTE *expect, USHORT waittime )
  155.     {
  156.     UBYTE buf[SCRATCHBUFSIZE];
  157.  
  158.     if ( strlen(send) >= SCRATCHBUFSIZE - 1 ) _FAIL_
  159.     sprintf(buf, "%s\r", send);
  160.     if ( !isend(buf) ) return(FALSE);
  161.     return( expectFromSer(expect, waittime) );
  162.     }
  163.  
  164. UBYTE *
  165. exSend( UBYTE *expect, USHORT waittime, UBYTE *send )
  166.     {
  167.     UBYTE *rxbufp;
  168.  
  169.     if ( strlen(send) >= SCRATCHBUFSIZE - 1 ) _FAIL_
  170.     if (rxbufp = expectFromSer(expect, waittime) )
  171.         {
  172.         UBYTE buf[SCRATCHBUFSIZE];
  173.         sprintf(buf, "%s\r", send);
  174.         if ( !isend(buf) ) return(NULL);
  175.         }
  176.     return(rxbufp);
  177.     }
  178.  
  179. BOOL
  180. sendToSer( UBYTE *send )
  181.     {
  182.     UBYTE buf[SCRATCHBUFSIZE];
  183.  
  184.     if ( strlen(send) >= SCRATCHBUFSIZE ) _FAIL_
  185.     strcpy(buf, send);    /* copying string to be able modify it */
  186.     return(isend(send));
  187.     }
  188.  
  189. BOOL
  190. isend( UBYTE *send )        /* this gets only called by sendEx(), exSend() and sendToSer() */
  191.     {
  192.     UBYTE *mptr = send;
  193.  
  194.     while ( *mptr != '\0' )
  195.         {
  196.         if ( *mptr++ == '\\' )
  197.             {
  198.             if      ( *mptr == 'r' ) *mptr = '\r';
  199.             else if ( *mptr == 'n' ) *mptr = '\n';
  200.             else if ( *mptr == 't' ) *mptr = '\t';
  201.             memmove(mptr - 1, mptr, strlen(mptr) + 1);
  202.             };
  203.         };
  204.  
  205.     if ( arg[A_VERBOSE] ) msg("Sending %s\n", send);
  206.  
  207.     Delay(2);
  208.     serialIOReq->IOSer.io_Command  = CMD_WRITE;
  209.     serialIOReq->IOSer.io_Data       = (APTR)send;
  210.     serialIOReq->IOSer.io_Length   = strlen(send);
  211.     if ( DoIO( (struct IORequest *)serialIOReq ) )
  212.         {
  213.         msg("failed to write to serial line\n");
  214.         return(FALSE);
  215.         }
  216.     return(TRUE);
  217.     }
  218.  
  219.  
  220. /*
  221. ** The next lines are stolen from the slip.device (Rhialto Seibert, Comodore)
  222. **
  223. ** ReadConfig
  224. **
  225. ** Attempt to read in and parse the driver's configuration file.
  226. **
  227. ** The files are named by ENV:SANA2/slip0.config where X is the decimal
  228. ** representation of the device's unit number.
  229. **
  230. */
  231.  
  232. #define LINEBUFFSIZE 1024
  233. #define NUMARGS 10
  234.  
  235. BOOL ReadConfig(STRPTR sanacfgfile, USHORT sanaUnit, struct SP *sp)
  236.     {
  237.     UBYTE *linebuff;
  238.     UBYTE buff[80] = "ENV:SANA2/";
  239.     UBYTE *termchar;
  240.     struct RDArgs *rdargs;
  241.     BPTR ConfigFile;
  242.     LONG arg[NUMARGS];
  243.     BOOL status = FALSE;
  244.     ULONG linenum=0;
  245.     UWORD i;
  246.  
  247.     sprintf(buff + ( strchr(sanacfgfile, ':') ? 0 : strlen(buff) ), sanacfgfile, (ULONG)sanaUnit);
  248.     if(ConfigFile = Open(buff,MODE_OLDFILE))
  249.         {
  250.         if(linebuff = AllocMem(LINEBUFFSIZE, MEMF_CLEAR|MEMF_PUBLIC))
  251.             {
  252.             if(rdargs = AllocDosObject(DOS_RDARGS, NULL))
  253.                 {
  254.                 while( FGets( ConfigFile, linebuff, LINEBUFFSIZE - 1) )
  255.                     {
  256.                     linenum++;
  257.                     if(linebuff[0] == '#') /* Skip comment lines */ continue;
  258.  
  259.                     rdargs->RDA_Source.CS_Buffer = linebuff;
  260.                     rdargs->RDA_Source.CS_Length = LINEBUFFSIZE;
  261.                     rdargs->RDA_Source.CS_CurChr = 0;
  262.  
  263.                     /* ReadArgs() requires that the line be null-terminated or funny things happen. */
  264.                     termchar = (UBYTE *) linebuff + strlen(linebuff);
  265.                     *termchar = '\n';
  266.                     termchar++;
  267.                     *termchar = 0;
  268.  
  269.                     for(i = 0; i < NUMARGS ; i++) arg[i] = NULL;
  270.                     if( ReadArgs( "SERNAME/A,SERUNIT/A/N,SERBAUD/A/N,IPSTR/A,CD=CARRIERDETECT/S,7WIRE/S,EOFMODE/S,MTU/K/N,THEREST/F", arg, rdargs ) )
  271.                         {
  272.                         status = TRUE;
  273.                         strcpy( sp->serDevName,    (UBYTE *)arg[0] );
  274.                         sp->serUnit            = *((ULONG *)arg[1]);
  275.                         sp->serBaudRate        = *((ULONG *)arg[2]);
  276.                         sp->listen2CD        =             arg[4] ? TRUE : FALSE;
  277.                         sp->serHWHS            =             arg[5] ? TRUE : FALSE;
  278.                         FreeArgs(rdargs);
  279.                         break;
  280.                         }
  281.                     else
  282.                         {
  283.                         msg("Error parsing sana arguments in %s", buff);
  284.                         break;
  285.                         }
  286.                     }
  287.                 FreeDosObject(DOS_RDARGS, rdargs);
  288.                 }
  289.             FreeMem(linebuff, LINEBUFFSIZE);
  290.             }
  291.         Close(ConfigFile);
  292.         }
  293.     return(status);
  294.     }
  295.  
  296.  
  297. VOID
  298. msg(UBYTE *msg, ...)
  299.     {
  300.     extern BPTR    mystderr;
  301.     va_list args;
  302.  
  303.     va_start(args, msg);
  304.      if(mystderr)
  305.         {
  306.         VFPrintf(mystderr, msg, args);
  307.         VFPrintf(mystderr, "\n", NULL);
  308.         }
  309.     else
  310.         {
  311.         struct Library *IntuitionBase;
  312.         static struct EasyStruct es;
  313.  
  314.         if(IntuitionBase = OpenLibrary("intuition.library", 37))
  315.             {
  316.             es.es_StructSize=sizeof(struct EasyStruct);
  317.             es.es_Flags = 0;
  318.             es.es_Title = prgname;
  319.             es.es_TextFormat = msg;
  320.             es.es_GadgetFormat = "OK";
  321.             EasyRequestArgs(NULL, &es, 0, args);
  322.             CloseLibrary(IntuitionBase);
  323.             };
  324.         }; 
  325.     va_end(args);
  326.     }
  327.  
  328. BOOL
  329. carrier()
  330.     {
  331.     /* modem online? */
  332.  
  333.     if (!serialIOReq) return(FALSE);
  334.         
  335.     serialIOReq->IOSer.io_Command  = SDCMD_QUERY;
  336.     if ( DoIO((struct IORequest *)serialIOReq) ) msg("Error: Query serial line.");
  337.     return( (BOOL)( (serialIOReq->io_Status & ( 1 << 5 ) ) == 0 ) );
  338.     }
  339.  
  340.